"""
@brief 可视化pid参数, 从而辅助pid调参.
    具体设计是, 单片机在调试PID时, 可将测量值, 误差, 输出值等参数
    通过蓝牙串口发送给电脑, 然后利用本程序读取并绘制实时波形.
    
    采用了自主编写的通信协议, 单片机发送数据的格式设计为各参数按顺序
    存放在values中, label设置为"pid". 本程序按照约定的values的顺序
    绘制各个参数的波形. 详见字典curves, 以及函数 draw_pid() 的实现.
    
    关于使用到的 pygame_scope 库, 详见 https://gitee.com/StoneTeleM/pygame_scope
    
@author Stone at BlueNet, GDOU
@date Oct. 2020
"""

import serial

import settings
from communication import Communication
from pygame_scope import Scope


# ===== ===== ===== ===== ===== =====
# 初始化串口和通信协议
# ===== ===== ===== ===== ===== =====
comm = Communication(port="com3", baudrate=115200, timeout=0.1)


# ===== ===== ===== ===== ===== =====
# 初始化示波器
# ===== ===== ===== ===== ===== =====
# 初始化外观
scope = Scope(sizex=800, sizey=400)
scope.axes.bgc = (0,0,0)

yaxis = scope.axes.yaxis
yaxis.color = (255,255,0)       # 设置y轴的颜色
yaxis.font_color = (255,255,0)  # 设置y轴刻度字体的颜色
yaxis.font_size = 26            # 设置y轴刻度字体的大小
yaxis.lim_upper =  2            # 设置y轴数值上限(limit upper)
yaxis.lim_lower = -2            # 设置y轴数值下限
yaxis.tick_step = 1             # 每相邻两个刻度之间相差多少数值
yaxis.spline_thickness = 2      # 坐标轴线宽

scope.panel.min_value = 0       # 拖动条最小取值
scope.panel.max_value = 3       # 拖动条最大取值
scope.panel.value = 1          # 设置滑块的值
# val = scope.value             # 获取滑块的值

scope.axes.drawer.x_step = 5    # 设置x轴步长(x方向上，曲线上每两个采样点相距几个像素)


# 初始化待绘变量
create_curve = scope.axes.create_curve

curves = {
    'r': create_curve((255, 255, 0)),   # 设定值
    'y': create_curve((0, 255, 255)),   # 测量值
    'e': create_curve((0, 0, 255)),     # 误差
    'x': create_curve((0, 255, 0)),     # 输出值
}


i = 0  # debug
def draw_pid():
    data = comm.read_data()
    
    if data is not None and data.label == 'pid':
        global i  # debug
        print(i, data)  # debug
        i += 1  # debug
        
        r, y, e, x = data.values
        
        curves['r'].append_sample(r)
        curves['y'].append_sample(y)
        curves['e'].append_sample(e)
        curves['x'].append_sample(x)
        
        scope.show()


scope.mainloop(user_task=draw_pid)


